package com.region.common.adapter.json.gson;

import com.google.gson.Gson;
import com.region.common.adapter.json.JSONAdapter;
import com.region.common.adapter.json.JSONAdapterFactory;
import com.region.common.adapter.json.convert.JsonConvertor;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * @author liujieyu
 * @date 2023/5/28 14:11
 * @desciption
 */
public class GsonAdapter<T> implements JSONAdapter<T> {

    private Gson gson = new Gson();

    public GsonAdapter() {
    }

    @Override
    public T getTarget() {
        return (T) gson;
    }

    @Override
    public String toJSONString(Object object) {
        for (JsonConvertor convertor : JSONAdapterFactory.getConvertors()) {
            if (convertor.isSerialized(object)) {
                return convertor.convertToString(object);
            }
        }
        return gson.toJson(object);
    }

    @Override
    public Object toObject(String json) {
        return this.toObject(json, Object.class);
    }

    @Override
    public <K> K toObject(String json, Class<K> clazz) {
        for (JsonConvertor convertor : JSONAdapterFactory.getConvertors()) {
            if (convertor.isDeserialized(json, clazz)) {
                return convertor.convertToObject(json, clazz);
            }
        }
        return gson.fromJson(json, clazz);
    }

    @Override
    public Object toObject(String json, Type type) {
        if (type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;
            if (parameterizedType.getActualTypeArguments() == null || parameterizedType.getActualTypeArguments().length == 0) {
                return toObject(json, parameterizedType.getRawType());
            } else {
                for (JsonConvertor convertor : JSONAdapterFactory.getConvertors()) {
                    if (convertor.isDeserialized(json, type)) {
                        return convertor.convertToObject(json, type);
                    }
                }
                return gson.fromJson(json, type);
            }
        } else if (type instanceof Class) {
            return toObject(json, (Class) type);
        }
        return null;
    }
}
